<template>
  <span>
    <el-upload
      :style="uploadStyle"
      action=""
      :class="['cm-affix', {'is-disabled': inputDisabled}]"
      :disabled="inputDisabled"
      :multiple=true
      :http-request="handleUpload"
      :file-list="fileList"
      :show-file-list=false
      :before-upload="handleBeforeUpload"
    >
      <el-button
        v-if="inputDisabled !== true"
        style="margin-right: 10px;"
        type="primary"
      >点击上传</el-button>
      <span v-if="affixId != null && affixId !== ''"
        class="pack-button"
        @click.stop="downloadPack()"
      >打包下载
      </span>
    </el-upload>

    <el-image-viewer
      v-if="showViewer"
      :loading="loading"
      :z-index="5000"
      :on-close="()=>{ showViewer = false }"
      :url-list="[imageUrl]"
    />

    <span v-for="(item, index) in fileList" class="file" :key="index">
      <span class="file-item" :class="[{'is-disabled': inputDisabled}]">
        <span class="file-name" :title="item.name">
          <span
            style="cursor: pointer"
            v-if="item.name.toLowerCase().endsWith('.pdf')
              || item.name.toLowerCase().endsWith('.ofd')

              || item.name.toLowerCase().endsWith('.doc')
              || item.name.toLowerCase().endsWith('.docx')
              || item.name.toLowerCase().endsWith('.wps')

              || item.name.toLowerCase().endsWith('.ppt')
              || item.name.toLowerCase().endsWith('.pptx')

              || item.name.toLowerCase().endsWith('.xls')
              || item.name.toLowerCase().endsWith('.xlsx')
              || item.name.toLowerCase().endsWith('.et')"
          >
            <span @click="showFile(item)">
              {{item.name}}
            </span>
          </span>
          <span
            style="cursor: pointer"
            v-else-if="item.name.toLowerCase().endsWith('.png')
              || item.name.toLowerCase().endsWith('.jpeg')
              || item.name.toLowerCase().endsWith('.jpg')
              || item.name.toLowerCase().endsWith('.bmp')
              || item.name.toLowerCase().endsWith('.gif')"
          >
            <span @click="showImage(item)">
              {{item.name}}
            </span>
          </span>
          <span v-else><span>{{item.name}}</span></span>
        </span>
        <span
          v-if="item.status===1"
          class="fa fa-regular fa-loader fa-spin file-upload"
          title="上传中..."
        ></span>
        <span
          v-if="item.status===2"
          class="fa fa-download file-download"
          title="下载"
          @click="downloadFile(item)"
        ></span>
        <span
          v-if="item.status===2"
          class="fa fa-trash file-delete"
          title="删除"
          @click="deleteFile(item)"
        ></span>
      </span>
    </span>
  </span>
</template>

<script setup>
import {ref, watch, onMounted} from 'vue';
import api from '@/http/api';
import tool from '@/utils/tool';
import {ElMessage, ElMessageBox, useDisabled} from 'element-plus';

const emit = defineEmits(['update:modelValue', 'change']);
const props = defineProps({
  modelValue: String,
  multiple: {
    type: Boolean,
    default: true
  },
  uploadStyle: {
    type: String,
    default: ''
  },
});

const uploadCnt = ref(0);
const affixId = ref('');
const fileList = ref([]);
const downloading = ref(false); //控制打包下载loading动画
const baseUrl = ref(import.meta.env.VITE_BASE_PATH);
const showViewer = ref(false);
const loading = ref(false);
const imageUrl = ref('');
const messageBox = ref(null);
const inputDisabled = useDisabled();

const showImage = (file) => {
  imageUrl.value = '';
  if (file && file.id) {
    imageUrl.value = baseUrl.value + 'affix/image/' + file.id;
    showViewer.value = true;
  }
};

const handleUpload = (file) => {
  return new Promise((resolve, reject) => {
    api.upload({'file': file.file, 'affixId': affixId.value}).then((res) => {
      uploadCnt.value--;

      let filters = fileList.value.filter(item => item.name === res.data.trueName && item.status === 1);
      if (filters.length > 0) {
        filters[0].id = res.data.id;
        filters[0].status = 2;
      }
      if (!props.multiple) {
        fileList.value = Object.assign([], fileList.value.filter(item => item.name === res.data.trueName));
        emit('change', fileList.value[0]);
      }
      resolve();
    }).catch(() => {
      uploadCnt.value--;
      reject();
    });
  });
};

const handleBeforeUpload = (file) => {
  if (affixId.value == null || affixId.value === '') {
    affixId.value = tool.uuid();
    emit('update:modelValue', affixId.value);
  }

  let isLt100M = file.size / 1024 / 1024 < 100;
  if (!isLt100M) {
    ElMessage.error("上传大小不能超过 100MB!");
  } else {
    if (!props.multiple) {
      fileList.value = Object.assign([], [{name: file.name, status: 1}]);
    } else {
      fileList.value.push({name: file.name, status: 1});
    }
    uploadCnt.value++;
  }

  return isLt100M;
};

const downloadFile = (file) => {
  api.downloadFileLocal(file.id);
};

const downloadPack = () => {
  downloading.value = true;
  if (affixId.value == null || affixId.value === '') {
    ElMessage.error("暂无附件！");
  }

  api.downloadAffixLocal(affixId.value);
};

const deleteFile = (file) => {
  ElMessageBox.confirm('请确认是否删除此文件？', '提示', {type: 'info'}).then(() => {
    api.deleteAffix(file.id).then(() => {
      fileList.value = fileList.value.filter(item => item.id !== file.id)
      if(fileList.value.length === 0){
        affixId.value = '';
        emit('update:modelValue', affixId.value);
      }
    });
  }).catch(()=>{});
};

const loadData = () => {
  fileList.value = [];
  if (typeof props.modelValue !== "undefined" && props.modelValue != null && props.modelValue !== "") {
    api.queryAffix(props.modelValue).then((res) => {
      if(res.data.length > 0){
        affixId.value = props.modelValue;
        for (let i=0;i<res.data.length;i++) {
          fileList.value.push({name: res.data[i].trueName, id: res.data[i].id, status: 2});
        }
      } else {
        affixId.value = '';
      }
    }).catch((res) => {
      ElMessage.error(res.message);
    });
  } else {
    affixId.value = '';
  }
};

const showFile = (file) => {
  if (file.name.toLowerCase().endsWith('.pdf')) {
    if (messageBox.value !== null) {
      messageBox.value.close();
      messageBox.value = null;
    }
    messageBox.value = ElMessageBox({
      message: '正在打开文件，请稍候...',
      type: 'success',
      showClose: true,
      duration: 0
    });

    api.download(file.id).then((res) => {
      let blob = new Blob([res.data], {type: 'application/pdf'})
      let href = window.URL.createObjectURL(blob); // 创建下载的链接
      window.open(href, '_blank');

      if (messageBox.value != null) {
        messageBox.value.close();
        messageBox.value = null;
      }
    }).catch((res) => {
      ElMessage.error(res.message);
    });
  }
};

watch(() => props.modelValue, (newVal) => {
  if (newVal === undefined || newVal == null || newVal === ''
      || affixId.value == null || affixId.value === ''
      || newVal !== affixId.value) {
    loadData();
  }
});

onMounted(() => {
  loadData();
});
</script>

<style scoped>
.file {
  width: 100%;
}
.file-item {
  width: 100%;
  display: flex;
  flex-direction: row;
  align-items: center;
  margin-top: 10px;
}
.file-name {
  overflow: hidden;
  min-width: 0;
}
.file-name > div {
  margin-right: 8px;
}

.file-name > div > div {
  display: flex;
  height: 18px;
  align-items: center;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}
.file-upload {
  font-size: 18px;
  margin-left: 5px;
}
.file-download, .file-delete {
  font-size: 18px;
  cursor: pointer;
  margin-left: 5px;
  width: 25px;
}
.file-download:hover, .file-delete:hover {
  color: #409EFF;
}
.file-item[class~=is-disabled] .file-delete {
  display: none;
}
.pack-button:hover {
  background: #66b1ff;
  border-color: #66b1ff;
  color: #FFF;
}
.pack-button:focus {
  color: #409EFF;
  border-color: #c6e2ff;
  background-color: #ecf5ff;
}
.pack-button {
  padding: 9px 15px;
  font-size: 14px;
  border-radius: 4px;
  color: #FFF;
  background-color: #409EFF;
  border-color: #409EFF;
  display: inline-block;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  -webkit-appearance: none;
  text-align: center;
  box-sizing: border-box;
  outline: 0;
  margin: 0;
  transition: .1s;
  font-weight: 500;
}
</style>
